package src.model.gameObject.ability;

import src.event.events.RemoveObject;
import src.model.gameObject.GameObject;
import src.model.gameObject.eventBrokers.HealthEventBroker;
import src.model.gameObject.eventInterfaces.HealthListener;
import src.model.gameWorld.GameWorldEventHandler;
import src.model.gameWorld.LookupTable;

/**
 * <b>Overview</b><br>
 * <p>This represents the health of a GameObject. A GameObject with this ability can
 * be attacked, take damage, be healed, and be destroyed. Armor is also encapsulated within this class.</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>Encapsulate all properties of health, damage, and healing, including destruction
 * when health gets too low, preventing healing beyond maximum health, and armor absorbing damage but not healing.</p>
 * <br><br>
 * <b>Collaborators</b>
 * <br>none<br>
 * <b>Implementor</b> - Tristan Lohman<br>
 * <b>Tester</b> - Brent<br>
 * @author Tristan
 *
 */
public class Health extends Ability implements HealthListener{

	private float currentHealth;
	
	/**
	 * Initializes the Health Ability.
	 * @param go The GameObject that owns this ability.
	 * @param lookup
	 */
	public Health(GameObject go, LookupTable lookup) {
		super(go, AbilityType.HEALTH, lookup);
		this.currentHealth = maxHealth();
		HealthEventBroker.register(super.gameObject(), this);
	}
	
	public void notifyHealthEvent(float modifyAmount) {
		if (modifyAmount < 0){
			modifyAmount *= armor();
		}
		
		if (modifyAmount <= -currentHealth){
			RemoveObject removeMe = new RemoveObject(super.gameObject());
			GameWorldEventHandler.fireEventNow(removeMe);
		}
		
		if (modifyAmount >= maxHealth() - currentHealth) {
			currentHealth = maxHealth();
		}
		
		currentHealth += modifyAmount;
		
	}
	
	/**
	 * The current health of the GameObject.
	 * @return Current health
	 */
	public float currentHealth(){ return currentHealth; }
	
	/**
	 * The maximum health of the GameObject.
	 * @return Maximum Health
	 */
	public float maxHealth(){	return super.getAttribute(AbilityAttributes.MAXIMUM);	}
	
	/**
	 * The armor value.
	 * @return how much armor.
	 */
	public float armor() {		return super.getAttribute(AbilityAttributes.STRENGTH);	}

	public void destroySub(){
		HealthEventBroker.unregister(super.gameObject());
	}
}
